package fl.ass.service.service.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import fl.ass.service.config.NacosConfiguration;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cmm.comm.facade.upload.constant.SysUlFilesRecConstant;
import cmm.service.core.framework.biz.BaseBizImpl;
import cmm.service.core.framework.dao.IBaseDao;
import cmm.user.facade.system.api.ISysUsrApiService;
import cmm.user.facade.system.condition.SysUsrQueryCondition;
import cmm.user.facade.system.dto.SysUsrDTO;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.DateUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.cmm.cache.framework.utils.PropertiesCacheUtils;
import cn.lb.framework.poi.excel.ExcelExportUtil;
import cn.lb.framework.poi.excel.entity.ExportParams;
import cn.lb.framework.poi.excel.entity.enmus.ExcelType;
import fl.ass.facade.condition.AssParkingMgQueryCondition;
import fl.ass.facade.condition.AssParkingQueryCondition;
import fl.ass.facade.constant.AssFileConstant;
import fl.ass.facade.dto.AssParkingDTO;
import fl.ass.facade.dto.AssParkingMgDTO;
import fl.ass.facade.dto.AssParkingValidDTO;
import fl.ass.facade.dto.MessageDTO;
import fl.ass.service.dao.AssParkingMapper;
import fl.ass.service.dao.AssParkingValidMapper;
import fl.ass.service.po.AssParking;
import fl.ass.service.service.IAssParkingMgService;
import fl.ass.service.service.IAssParkingService;
import fl.ass.service.transform.AssParkingTransform;
import fl.ass.service.transform.AssParkingValidTransform;

/**
 * @Description: 停车场表 服务层接口实现
 * @Description: 类中已经实现了简单增删改查操作,可以直接使用,如果有需要重写该方法即可：
 * @Description: 1、add(TVO entity) 2、removeById(Long id) 3、modify(DTO entity) 4、selectById(Long id)	5、searchListPage(Pager page) 7、searchList(DTO dto)   
 * @Description: 业务层方法名称前缀：新增：add* 删除：remove* 修改：modify* 查询对象：select* get* 批量：batch* 查询集合：search*
 */
@Service
public class AssParkingServiceImpl extends BaseBizImpl<AssParking, AssParkingDTO, AssParkingQueryCondition> implements IAssParkingService {
	
	private static final Logger logger = LoggerFactory.getLogger(IAssParkingService.class);
	
	@Autowired
	private AssParkingMapper assParkingMapper;
	
	@Autowired
	private AssParkingValidMapper assParkingValidMapper;
	
	@Autowired
	private IAssParkingMgService assParkingMgService;//资产管理员服务
	
	@Autowired
	private ISysUsrApiService sysUsrApiService;//系统用户API 暴露服务

    @Autowired
    private NacosConfiguration nacosConfiguration;
	
	@Override
	public List<AssParkingDTO> searchList(AssParkingQueryCondition condition) throws BaseException {
		if(null == condition) return new ArrayList<AssParkingDTO>();
		List<AssParking> list = this.assParkingMapper.selectList(condition);
		return AssParkingTransform.toDTOList(this.getManagersInfo(list,condition));
	}
	
	@Override
	public IBaseDao<AssParking,AssParkingQueryCondition> getDao() {
		return this.assParkingMapper;
	}

	/* (non-Javadoc)
	 * @see fl.ass.service.service.IAssParkingService#saveAssParkingValid(fl.ass.facade.dto.AssParkingValidDTO)
	 */
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public MessageDTO<String> saveAssParkingValid(AssParkingValidDTO dto) {
		MessageDTO<String> response = new MessageDTO<String>();
		if(null != dto){
			AssParkingDTO parkingDto = dto.getAssParkingDTO();
			if(null != parkingDto){
				int num = assParkingMapper.update(AssParkingTransform.toPO(parkingDto));
				response.setNum(num);//设置更新返回值
			}
			Long id = assParkingValidMapper.insert(AssParkingValidTransform.toPO(dto));
			response.setId(id);//设置插入主键值
		}
		return response;
	}
	
	/**
	 * 导出停车场信息
	 * @param condition
	 * @param orgCd
	 * @return
	 * @throws BaseException
	 */
	@Override
	public String exportAssParking(AssParkingQueryCondition condition,String orgCd) throws BaseException {
		if(null==condition){
			//throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "查询条件不能为空.");
		}
		if(StringUtils.isEmpty(orgCd)){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "组织架构代码不能为空");
		}
		List<AssParking> exportAssParkList = this.assParkingMapper.selectList(condition);
		if(CollectionUtils.isEmpty(exportAssParkList)){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_601, "没有符合要求的停车场信息.");
		}
		String path = this.exportAssParkToExcel(this.getManagersInfo(exportAssParkList,condition),orgCd);
		return path;
	}
	
	/**
	 * 导出停车场信息
	 * @param
	 * @return
	 */
	private String exportAssParkToExcel(List<AssParking> parkList,String orgCd)throws BaseException{
		ExportParams params = new ExportParams(null, null, ExcelType.XSSF);
		params.setTitleHeight((short) 5);
        params.setColor(HSSFColor.LIGHT_TURQUOISE.index);//表头颜色
        params.setHeaderColor(HSSFColor.WHITE.index);//间隔颜色-未启用
        params.setStyle(ExcelExportStylerColorImpl.class);
		Workbook workbook = ExcelExportUtil.exportExcel(params,AssParking.class, parkList);
			
		String filePath = AssFileConstant.SYS_EXPORT_PARK_SAVE_DIR;
		String serverFilePath = this.getServerFilePath(filePath); 
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String filename = "停车场信息" + sdf.format(new Date());
		serverFilePath = serverFilePath + filename + ".xlsx";
		FileOutputStream fos = null;
		try {
			fos=new FileOutputStream(serverFilePath);
			workbook.write(fos);
			fos.flush();
		} catch (FileNotFoundException e) {
            BaseLogUtils.newLogger("导出停车场信息失败 文件找不到 FileNotFoundException").setThrowable(e).info();
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_700,e.getMessage());
		} catch (Exception e) {
            BaseLogUtils.newLogger("导出停车场信息失败 Exception").setThrowable(e).info();
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_700, BaseExceptionConstant.BASE_EXCEPTION_CODE_700_NAME);
		}finally {
			try {
				if(null!=fos){
					fos.close();
				}
			} catch (IOException e) {
			    BaseLogUtils.newLogger("导出停车场信息失败").setThrowable(e).info();
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_700, BaseExceptionConstant.BASE_EXCEPTION_CODE_700_NAME);
			}
		}
		BaseLogUtils.newLogger("导出停车场信息").setKeys("文件根路径.serverFilePath:" + serverFilePath).info();
		// String serverPath = serverFilePath.replace(PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH), PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_SERVER_PATH));
        String serverPath = serverFilePath.replace(nacosConfiguration.getUlfilesRootPath(), nacosConfiguration.getUlfilesServerPath());
		return serverPath;
	}
		
	/**
	 * 创建文件服务器保存路径
	 */
	private String getServerFilePath(String filePath)throws BaseException{
		//String prifixPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH);//根目录
        String prifixPath = nacosConfiguration.getUlfilesRootPath();//根目录
		StringBuffer savePath = new StringBuffer(prifixPath);//最终保存路径
		if(!savePath.toString().endsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)){//判断是否以"/"结尾,不是加入斜杠
    		savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
    	}
//		savePath.append(PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.UPLOAD_COSTOMER_PATH));//自定义代码-其中包括系统代码
        savePath.append(nacosConfiguration.getUlfilesCustomerPath());//自定义代码-其中包括系统代码
		if(StringUtils.isNotEmpty(filePath)){//如果不等于空则加入
			if(filePath.startsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)){//判断是否以"/"开头
				savePath.append(filePath.substring(1));
			}else{
				savePath.append(filePath);
			}
			
		}
		if(!savePath.toString().endsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)){//判断是否以"/"结尾
    		savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
    	}
		String currentTime = DateUtils.formatDateToString(new Date(), DateUtils.YYYYMMDD);
		savePath.append(currentTime);
		savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
	    //检查目录
		File pathFile = new File(savePath.toString());
	    if (!pathFile.exists()) {
	        BaseLogUtils.newLogger("文件保存服务器路径不存在需要创建").setKeys("savePath" + savePath).info();
	    	// 文件夹不存在，创建文件夹
	    	boolean createPath = pathFile.mkdirs();
	    	if(!createPath){
	    		throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "服务器附件目录未创建成功!");
	    	}
	    }
	    return savePath.toString();
	}
	
	/**
	 * 根据城市代码获取停车场名称数据
	 * @param
	 * @return
	 * @throws BaseException
	 */
	@Override
	public List<AssParkingDTO> searchParkNmByRgnCd(String provinceCd, String cityCd, String parkId) throws BaseException {
		List<AssParkingDTO> list = new ArrayList<AssParkingDTO>();
		//查询数据库中的停车场名称信息
		AssParkingQueryCondition qc = new AssParkingQueryCondition();
		qc.setProvinceCd(provinceCd);
		qc.setCityCd(cityCd);
		qc.setParkStatus(1);//有效期内-合作中
		List<AssParking> selectList2 = this.assParkingMapper.selectList(qc);
		list = AssParkingTransform.toDTOList(selectList2);
		//目前选择的停车场
		if(StringUtils.isNotEmpty(parkId)){
			qc.setId(Long.parseLong(parkId));
			qc.setParkStatus(2);//有效期内-已到期
			List<AssParking> selectList1 = this.assParkingMapper.selectList(qc);
			list.addAll(AssParkingTransform.toDTOList(selectList1));
		}
		return list;
	}
	
	/**
	 * 时间：2018-11-07
	 * 开发者：JL
	 * 功能：获取资管员工号及姓名
	 */
	public List<AssParking> getManagersInfo(List<AssParking> assList,AssParkingQueryCondition assQc) {
		List<AssParking> result = new ArrayList<AssParking>(); 
		//遍历列表结果
		for(AssParking po : assList){
			//1.根据停车场ID查询相应资管员列表
			AssParkingMgQueryCondition mgQc = new AssParkingMgQueryCondition();
			mgQc.setParkId(po.getId());
			mgQc.setIsDel(0);
			List<AssParkingMgDTO> mgList = this.assParkingMgService.searchList(mgQc);
			List<Long> usrIds = new ArrayList<Long>();
			for(AssParkingMgDTO mg : mgList){
				usrIds.add(mg.getManagerId());
			}
			//2.根据资管员ID查询资管员名称，并拼接“史勇[1000945],于瑞超[1000897]”这种形式
			String assManagers = "";
			if(CollectionUtils.isNotEmpty(usrIds)){
				SysUsrQueryCondition usQc = new SysUsrQueryCondition();
				usQc.setSysCd("11000");
				usQc.setUsrIds(usrIds);
				List<SysUsrDTO> usrList = this.sysUsrApiService.searchSysUsrList(usQc);
				int i=0;
				for(SysUsrDTO usr : usrList){
					i++;
					assManagers = assManagers.concat(usr.getRefRlNm()+"["+usr.getUsrNm()+"]");
					if(i < usrList.size()){
						assManagers = assManagers.concat(",");
					}
				}
			}
			po.setAssManagers(assManagers);
			if(StringUtils.isNotEmpty(assQc.getAssManagers())){
				if(assManagers.contains(assQc.getAssManagers())){
					result.add(po);
				}
			}
		}
		//判断是否按照“资产管理员”模糊查询停车场信息
		if(StringUtils.isNotEmpty(assQc.getAssManagers())){
			return result;
		}else{
			return assList;
		}
	}
}

